package com.social.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rabbitmq.client.Channel;
import com.social.dao.ActivityDao;
import com.social.dao.ActivityRegisterDao;
import com.social.dao.ComplaintDao;
import com.social.pojo.Activity;
import com.social.pojo.ActivityRegister;
import com.social.pojo.Complaint;
import com.social.pojo.Result;
import com.social.service.ActivityRegisterService;
import com.social.service.ActivityService;
import com.social.utils.RedisIdWorker;
import com.social.utils.UserHolder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;

import java.io.IOException;
import java.time.LocalDateTime;



import static com.social.constant.MessageConstant.*;
import static com.social.constant.RabbitMqConstants.*;
import static com.social.constant.RedisConstants.ACTIVITY_NUMBER_KEY;


/**
 * @className: ActivityRegisterServiceImpl
 * @description: TODO 类描述
 * @author: XiaoXu
 * @date: 2022/10/24 20:56
 **/
@Service
public class ActivityRegisterServiceImpl extends ServiceImpl<ActivityRegisterDao,ActivityRegister> implements ActivityRegisterService{


    private ActivityService activityService;

    @Autowired
    public void setActivityService(@Lazy ActivityService activityService){
        this.activityService = activityService;
    }
    @Resource
    private RedisIdWorker redisIdWorker;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RabbitTemplate rabbitTemplate;
    // TODO 注册活动，消息队列
    @Override
    public Result registerActivity(Long id) {
        /**
            * @Author XiaoXu
            * @Date 2022/10/28
            * @Param [id]
            * @Return Result
            * @Description 注册活动
         */

        System.out.println("报名活动");
        String json = stringRedisTemplate.opsForValue().get(ACTIVITY_NUMBER_KEY);
        //System.out.println("1");
        if(json == null){
            Long number = query().eq("activityId", id).eq("state",1).eq("category",0).count();
            Activity activity = activityService.getById(id);
            long noRegister = activity.getNumber() - number;
            System.out.println("number:"+activity.getNumber()+" "+number+" "+noRegister+JSONUtil.toJsonStr(noRegister));
            stringRedisTemplate.opsForValue().set(ACTIVITY_NUMBER_KEY, String.valueOf(noRegister));
            json = String.valueOf(noRegister);
        }
       // System.out.println("1"+json);
        Long number = Long.valueOf(json);
        number = number;
        //System.out.println("1");
        if(number == 0){
            return Result.fail(OPERATE_DATA_FAIL,"活动报名人数已满");
        }
       // System.out.println("1");
        Activity activity = activityService.getById(id);

        if(activity == null){
            return Result.fail(QUERY_DATA_FAIL,"活动不存在");
        }
        if(activity.getNumber() == 0){
            return Result.fail(OPERATE_DATA_FAIL,"活动报名人数已满");
        }
        LocalDateTime now = LocalDateTime.now();
        if(now.isBefore(activity.getRegisterDate())){
            return Result.fail(OPERATE_DATA_FAIL,"活动报名未开始");
        }
        if(now.isAfter(activity.getEndTime())){
            return Result.fail(OPERATE_DATA_FAIL,"活动已经结束");
        }
        Long userId = UserHolder.getUser().getId();
        Long count = query().eq("userId", userId).eq("activityId", id).eq("state",1).count();
        System.out.println("userId" +userId+"activityId"+activity.getId());
        System.out.println(count);
        if (count > 0){
            return Result.fail(OPERATE_DATA_FAIL,"用户已报名");
        }

        boolean isSuccess = activityService.update()
                .setSql("register = register + 1")
                .eq("id", id)
                .lt("register", activity.getNumber())
                .update();
        if(!isSuccess){
            return Result.fail(UPDATE_DATA_FAIL,"活动报名失败");
        }

        ActivityRegister register = new ActivityRegister();
        register.setActivityId(activity.getId());
        register.setId(redisIdWorker.nexId(activity.getId().toString()));
        register.setUserId(userId.longValue());

        stringRedisTemplate.opsForValue().decrement(ACTIVITY_NUMBER_KEY);
        //消息队列
        rabbitTemplate.convertAndSend(ACTIVITY_EXCHANGE,ACTIVITY_REGISTER_ROUTING, register);
        return Result.ok(OPERATE_DATA_SUCCESS,register.getId());
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result repealActivity(Long id) {
        try {
            boolean isSuccess = update().eq("id", id).set("state", 2).eq("category",0).update();
            if(!isSuccess){
                return Result.fail(UPDATE_DATA_FAIL,"撤销失败");
            }

            boolean one = activityService.update()
                    .setSql("register = register + 1")
                    .eq("id", id)
                    .update();

            if(!one){
                throw new Exception();
            }
            return Result.ok(OPERATE_DATA_SUCCESS);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            Result.fail(UPDATE_DATA_FAIL,"撤销失败");
        }
        return Result.ok(OPERATE_DATA_SUCCESS);
    }

    @RabbitListener(queues = ACTIVITY_REGISTER_QUEUE)
    public void listenerActivity(Message message , Channel channel) throws IOException {
        String json = new String(message.getBody());
        System.out.println(json);
        try {
            ActivityRegister activityRegister = JSONUtil.toBean(json, ActivityRegister.class);
            //验证是否撤销了报名
            ActivityRegister one = query().eq("userId", activityRegister.getUserId()).eq("activityId", activityRegister.getActivityId()).eq("state", 2).one();
            if(one != null){
                //撤销报名,重新报名
                one.setState(1);
                one.setUpdate_date(LocalDateTime.now());
                boolean isUpdate = updateById(one);
                if (!isUpdate){
                   throw  new Exception();
                }
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                return ;
            }

            activityRegister.setDate(LocalDateTime.now());
            activityRegister.setUpdate_date(LocalDateTime.now());
            activityRegister.setState(1);
            boolean isSuccess = save(activityRegister);

            if (!isSuccess) {
                throw  new Exception();
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
            log.error("异常消费",e.fillInStackTrace());
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
        }
    }

//    @RabbitListener(queues = ACTIVITY_REGISTER_QUEUE)
//    public void listenerActivity(String json){
//        try {
//            ActivityRegister activityRegister = JSONUtil.toBean(json, ActivityRegister.class);
//            //验证是否撤销了报名
//            Long userId = UserHolder.getUser().getId();
//            ActivityRegister one = query().eq("userId", userId).eq("activityId", activityRegister.getActivityId()).eq("state", 2).one();
//            if(one != null){
//                one.setState(1);
//                boolean isUpdate = updateById(one);
//                if (!isUpdate){
//                    rabbitTemplate.convertAndSend(ACTIVITY_EXCHANGE,ACTIVITY_REGISTER_ROUTING,json);
//                }
//                return ;
//            }
//
//            activityRegister.setDate(LocalDateTime.now());
//            activityRegister.setUpdate_date(LocalDateTime.now());
//            activityRegister.setState(1);
//            boolean isSuccess = save(activityRegister);
//
//            if (!isSuccess) {
//                rabbitTemplate.convertAndSend(ACTIVITY_EXCHANGE,ACTIVITY_REGISTER_ROUTING, json);
//            }
//        }catch (Exception e){
//            log.error("异常消费",e.fillInStackTrace());
//        }
//    }
}
